# -*- coding:utf-8 -*-

'''
    Some useful codes to perform aod
'''
import numpy as np
from satellite import *
from satProp import LIGHTSPEED
import copy

def genLinkPair(satnum):
    '''
        generate link pair for given satnum
        the index of sat will start from 1
        NOTE: if satnum is odd, then one of the sat will exclude from the link 
    '''
    assert isinstance(satnum,int), 'satnum must be an integer'
    satindices = list(range(1,satnum+1))
    links = []
    for i in range(1,int(satnum/2+1)):
        index1    = int(np.floor(len(satindices)*np.random.rand()))
        emitsat   = satindices[index1]
        satindices.pop(index1)

        index2    = int(np.floor(len(satindices)*np.random.rand()))
        recsat      =  satindices[index2]
        satindices.pop(index2)

        links.append([emitsat,recsat])
    return links

def linkdata(satTrans,satRec,linktime,start = True):
    '''
        compute link true distance measurement.
        NOTE it will change the states of the satellite instances
        NOTE satellite currrentState will not prop to the link time, instead, linktime will be set to satellite immediately.
        satTrans: transmit satllite
        satRec: receive satllite
        linktime: link received time(start = False) or start time(start = True)
    ''' 
    MAX_ITER_TIME_COMMONMODEL =  30
    MIN_ITER_STEP_COMMONMODEL =  1e-6
    if start:
        satproped = satRec
        anotherSat = satTrans
    else:
        satproped = satTrans
        anotherSat = satRec
    satproped.setCurTime(linktime)
    anotherSat.setCurTime(linktime)
    propStartTime = linktime
    iterTime = 0
    transmitTime =0.0
    totalTime = 0.0 
    factor = 1
    while(True):
        iterTime = iterTime +1 
        distSign = 1 if start else -1
        # deltaDist =distSign* (np.linalg.norm(satproped.kine.mean[0:3]-anotherSat.kine.mean[0:3]))-totalTime* LIGHTSPEED
        deltaDist = 10
        transmitTime = factor* deltaDist / LIGHTSPEED 
        # if transmitTime == 0:
        #     print "i am break"
        #     break
        satproped.prop(endTime = propStartTime+transmitTime)
        propStartTime = propStartTime+ transmitTime
        totalTime = totalTime +transmitTime 
        # print transmitTime/factor
        if abs(transmitTime) < MIN_ITER_STEP_COMMONMODEL or iterTime >= MAX_ITER_TIME_COMMONMODEL:
            '''
                Here we just use simplified elliptical model for orbit modeling
            '''
            if iterTime >= MAX_ITER_TIME_COMMONMODEL: 
                print "iteration overflow\n"
            break    
    dist = np.linalg.norm(satproped.kine.mean[0:3]-anotherSat.kine.mean[0:3])
    # rel_vel = np.linalg.norm(satproped.kine.mean[3:6]-anotherSat.kine.mean[3:6])
    # print "rel_vel:",rel_vel
    otherlinkTime = propStartTime

    return dist,otherlinkTime

if __name__ == "__main__":
    print genLinkPair(12)